﻿#region Creditos

/* Autor: Edilberto Sánchez Forero	*/
/* Email: esanchezfo@gmail.com		*/
/* Licencia: LGPL, Software Libre	*/
/* País: Colombia, Bogotá			*/

#endregion

#region Librerias

using System;
using System.Runtime.Serialization;
using System.Collections.Generic;
using System.Xml.Serialization;
using System.Data.Linq.Mapping;
using System.Data.Linq;

#endregion


namespace ESF.General.Entity
{
	[DataContract]
	[Serializable]
	[Table(Name="esf_sso.BasicReference")]
	public class BasicReference : BaseEntity, IBasicReference, IAuditableEntity, IEquatable<BasicReference>, IPagginableInfo, IComparable<IBasicReference>, IComparable
	{
		#region Constantes

		public const int NAME_MAXLENGTH = 500;

		#endregion


		#region Miembros

		[Column (IsDbGenerated=true, IsPrimaryKey=true)]
		[DataMember]
		public int? ID { get; set ; }
		
		[Column]
		[DataMember]
		public string Code { get; set ; }
		
		[Column]
		[DataMember]
		public string Name { get; set ; }
		
		[Column]
		[DataMember]
		public string Description { get; set ; }

		[Column]
		[DataMember]
		public bool? IsEnabled { get; set; }

		[Column]
		[DataMember]
		public int? Order { get; set; }
		
		[Column]
		[DataMember]
		public string Extra_I { get; set ; }
		
		[Column]
		[DataMember]
		public string Extra_II { get; set ; }
		
		[Column]
		[DataMember]
		public string Extra_III { get; set ; }

		#endregion
		

		#region Auditoria

		[DataMember]
		[Column]
		public DateTime? CreationDateTime { set; get; }
		
		[DataMember]
		[Column]
		public DateTime? LastUpdateDateTime { set; get; }
		
		[DataMember]
		[Column]
		public string UserCreationAlias { set; get; }
		
		[DataMember]
		[Column]
		public string UserLastUpdateAlias { set; get; }

		#endregion


		#region Miembros de IEquatable<BasicReference>

		public override int GetHashCode()
		{
			if (ID != null) { return ID.GetHashCode (); }
			
			if (Code != null) { return Code.GetHashCode (); }
			
			return 0;
		}


		public bool Equals(BasicReference pOther)
		{
			return Equals(this, pOther);
		}


		public override bool Equals(object pOther)
		{
			return Equals(this, pOther as IBasicReference);
		}
		

		public bool Equals (IBasicReference pOther)
		{
			return Equals (this, pOther);
		}


		public static bool Equals (IBasicReference pA, IBasicReference pB)
		{
			if (pA == null || pB == null) { return false; }

			if (pA.ID != null && pB.ID != null)
			{
				return (pA.ID.Value == pB.ID.Value);
			}

			if (pA.Code != null && pB.Code != null)
			{
				return (pA.Code == pB.Code);
			}

			if (pA.Name != null && pB.Name != null)
			{
				return (pA.Name == pB.Name);
			}

			return false;
		}

		#endregion


		#region BasicReferenceType

		[Column]
		[DataMember]
		public int? BasicReferenceTypeID { set; get; }

		[NonSerialized]
		[XmlIgnore]
		[IgnoreDataMember]		
		private EntityRef<BasicReferenceType> _BasicReferenceType = new EntityRef<BasicReferenceType> ();

		[XmlIgnore]
		[IgnoreDataMember]		
		[Association(Name = "FK_BasRef_BasRefType_Type", IsForeignKey = true, Storage = "_BasicReferenceType", ThisKey = "BasicReferenceTypeID")]		
		public BasicReferenceType BasicReferenceType 
		{
			set 
			{ 
				_BasicReferenceType.Entity = value; 

				if (value != null)
				{
					BasicReferenceTypeID = value.ID;
				}
			} 
			get 
			{
				if (BasicReferenceTypeID != null)
				{
					return new Entity.BasicReferenceType () { ID = BasicReferenceTypeID.Value };
				}
				
				return _BasicReferenceType.Entity; 
			} 
		}

		#endregion


		#region Util Fields

		public int [] filBasicReferenceTypeIDs { set; get; }

		
		[DataMember]
		public string Value { set; get; }


		public List<BasicReference> Children { set; get; }


		[IgnoreDataMember]
		[XmlIgnore]
		public Dictionary<string,object> ExtraValues { get; set; }

		#endregion


		#region Constructor

		public BasicReference ()
		{
			Children = new List<BasicReference> ();

			ExtraValues = new Dictionary<string,object> ();

			CreationDateTime = DateTime.Now;

			LastUpdateDateTime = DateTime.Now;

			IsEnabled = true;
		}

		#endregion


		#region ToString

		public static string ToString<BR> (BR pBR) where BR : BasicReference
		{
			if (pBR == null) { return string.Empty; }
			
			return string.Format ("ID: {0}, Code: {1}, Name: {2}, Type: {3}", pBR.ID, pBR.Code, pBR.Name, (pBR.BasicReferenceType == null ? string.Empty : pBR.BasicReferenceType.ID.ToString ()));
		}


		public override string ToString()
		{
			string result;
			
			
			result = string.Empty;
		
			if (!string.IsNullOrEmpty (Name))
			{
				result += Name;
			}

			return result;
		}



		public static string Concatenate<BR>(string pSeparator, List<BR> pList) where BR : BasicReference
		{
			return TextHelper.Concatenate<BR>(pSeparator, pList);
		}
		
		#endregion


		#region Methods of IComparable

		public int CompareTo(IBasicReference pOther)
		{
			if (Order != null && pOther.Order != null)
			{
				return Comparer<int>.Default.Compare (Order.Value, pOther.Order.Value);
			}

			return Comparer<string>.Default.Compare (Name, pOther.Name);
		}


		public int CompareTo (object pOther)
		{
			if (pOther is IBasicReference)
			{
				return CompareTo (pOther as IBasicReference);
			}

			throw new ArgumentException (string.Format ("pOther must implement IBasicReference but is {0}", (pOther == null ? "NULL" : pOther.GetType ().ToString ())));
		}

		#endregion
	}
}
